<?php

namespace app\job;

//use app\api\model\FailedJob;
use think\db\exception\ModelNotFoundException;
use think\queue\Job;
use Throwable;
use think\Log;

abstract class BaseJob
{
    /**
     * 最大重试次数
     */
    const MAX_TRIES = 3;

    /**
     * 重试延迟时间
     */
    const RETRY_AFTER = 60 * 3;

    abstract public function handle(Job $job, $data);

    /**
     * 执行任务
     *
     * @param  \think\queue\Job $job
     * @param  mixed $data
     * @return void
     *
     * @throws \Throwable
     */
    public function fire(Job $job, $data)
    {
        try {
            $this->handle($job, $data);

            $job->delete();
        } catch (Throwable $e) {
            if ($e instanceof ModelNotFoundException) {
                return $job->delete();
            }

            if ($job->attempts() < static::MAX_TRIES) {
                $job->release(static::RETRY_AFTER);
            } else {
                $this->handleFailed($job, $e);
                $job->delete();
            }
//            \Lock::instance()->run(function () use ($e) {
//                $time = date('Y-m-d H:i:s');
//                $str = "{$time}<br>Error:{$e->getMessage()}<br>{$e->getFile()}:{$e->getLine()}<br>{$e->getTraceAsString()}";
//                queue(EmailErrorWarn::class, $str);
//            }, "error_email_". md5($e->getFile().$e->getMessage().$e->getLine()), 300);

            throw $e;
        }
    }

    /**
     * 记录失败任务
     *
     * @param  \think\queue\Job $job
     * @param  \Throwable $e
     * @return void
     */
    protected function handleFailed($job, $e)
    {
        Log::info((string) $e);
//        FailedJob::create([
//            'name' => $job->getName(),
//            'queue' =>  $job->getQueue(),
//            'payload' => $job->getRawBody(),
//            'exception' => (string) $e,
//        ]);
    }
}
